from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from pyexpat.errors import messages
from copy import deepcopy
from src.choice_api.utils import timestamp2timestr

extrac_prompt = """You are an expert extraction algorithm. Only extract relevant information from the text. do not change the order of extracting words,eg '获取前三天的水流量' the extracted keywords are from the previous '前三天'eg '本月3号到5号' the extracted keywords are from the previous ['本月3号', '5号'].If you do not know the value of an attribute asked to extract,and request to only output standard time format %Y-%m-%d %H:%M:%S、%Y-%m-%d、%Y-%m、%Y.return null for the attribute's value.If there are multiple entities, please add them to the list"""

standardize_prompt = """You are a helpful assistant，only output %Y-%m-%d %H:%M:%S"""

rewrite_prompt = """You are a helpful assistant，Please replace the time text description with standard time in the texteg '获取去年情人节晚上8点到9点的财务数据 [2024-02-14 20:00:00, 2024-02-14 21:00:00]' replace with 获取2024-02-14 20:00:00到2024-02-14 21:00:00的财务数据.Only output the replaced text eg. '获取2024-02-14 20:00:00到2024-02-14 21:00:00的财务数据"""


def get_time_extraction(question: str):
    messages = [
        SystemMessage(content="""你是一个数据处理专家，你需要从用户问题中提取有用的时间,并表示为规定的时间

你需要知道的时间表示方法：
1.Y表示年，m表示月，d表示日,H表示小时，M表示分钟，S表示秒，W表示周，Q表示季度：
2.表示具体一天的时刻 比如 2024Y12m02d18H05M20S 代表 2024年12月2日18时05分20秒。2025Y1m表示2025年1月
3.表示一段时间 比如  2024Y02m12d16H34M21S~2025Y01m07d18H34M10S 代表 2024年2月12日16时34分21秒至2025年1月7日18时34分10秒这段时间
4.表示过去：使用'-'。 过去24小时是 -24H~now，过去一年是 -1Y~now。
5.表示上一段时间：使用'--'。10天前是 --10d ，同理昨天是 --1d，上一年是 --1Y.
6.表示这一段时间：使用'--'。 这一周是 --0W，这一月是 --1m。
7.表示未来: 使用'+'。 7天后 +7d，3个月后 +3m，20分钟后 +20M
8.周的表示方法：2024Y12W 表示2024年12周。2024Y05m2W表示5月的第2周；-1W表示上一周
9.表示季度方法：2024Y3Q 表示2024年第三季度。
10.表示今天：now表示今天
11.常见表达：过去8天、最近8天、8天内表示为 -8d~now。过去两周表示为 -2W~now。过去一个季度表示为-Q~now。2024年3月和2025年1月表示为 2024年3月,2025年1月。
12.使用'*'可以表示一段时间，使用'*+'表示后（最后）一段时间,使用'*-'表示靠前（最开始）一段时间。2024Y*-3m表示2024年前（最开始）三个月。2021Y*+1Q表示2021年后（最后）1个季度。1982Y*+2Q表示1982年后（最后）2个季度。2012Y*+3Q表示2012年后（最后）3个季度。1873Y*-1Q表示1873年前（最开始）1个季度。1764Y*-2Q表示1764年前（最开始）2个季度。2000Y*-3Q表示2000年前（最开始）三个季度。2007Y*+4d表示2007年后（最后）4天。2017年1月*-5d表示2017年1月前（最开始）5天。
13.对于用户缺省的年或月补全，2024年3月和5月 表示为 2024Y3m,2024Y5m。2024年7月12日、13日和15日表示为 2024Y7m12d,2024Y13d,2024Y15d
14. 当前时间2025年4月，如果用户缺省的年或月请用2025年4月补全

要求：
1.根据用户问题提取时间，只返回一个json，如下格式：
```json
{"time":{"<问题中提取出的时间1>":"<上述的时间表达方式的时间1>"}}
```
2.如果用户问题中未有时间，则返回NONETIME标志
```json
{"time":"NONETIME"}
```
3.问题中提取出的时间与原文一致"""),
        HumanMessage(content="根据问题`查询2025年1月1号到4号的生化A系统硝氮仪和排放池总磷的数据进行对比`提取时间。"),
        AIMessage(content="```json\n{\"time\":{\"2025年1月1号到4号\":\"2025Y1m1d~2025Y1m4d\"}}\n```"),
        HumanMessage(
            content="根据问题`今天是2022年2月7日，比较2012年7月12日和2024年1月5日AV-T20610_M_SET、AV-T20617_M_SET的数据`提取时间。"),
        AIMessage(
            content="```json\n{\"time\":{\"2012年7月12日\":\"2012Y07m12d\",\"2024年1月5日\":\"2024Y01m05d\"}\n```"),
        HumanMessage(
            content="根据问题`查询过去67天和上一周厌氧进口COD数据、南侧风机_出口温度和模拟量实际值_TI_T20601_V的数据`提取时间。"),
        AIMessage(content="```json\n{\"time\":{\"过去67天\":\"-67d~now\",\"上一周\":\"--1W\"}\n```"),
        HumanMessage(
            content="根据问题`查询1998年最后三季度、2003年第一季度、2000年3月、2010年9月28日、2009年5月最后12天、2011年最后23天、2023年前46天、2021年开始46天、过去34天、4周前和昨天模拟量实际值_AI_T10101_V和模拟量实际值_FQI_T20203_V的数据进行对比`提取时间。"),
        AIMessage(
            content="```json\n{\"time\":{\"1998年后三季度\":\"1998Y*+3Q\",\"2003年第一季度\":\"2003Y1Q\",\"2000年3月\":\"2000Y3m\",\"2010年9月28日\":\"2012Y9m28d\",\"2009年5月最后12天\":\"2009Y5m*+12d\",\"2011年最后23天\":\"2011Y*+23d\",\"2023年前46天\":\"2023Y*-46d\",\"2021年最开始46天\":\"2021Y*-46d\",\"过去34天\":\"-34d~now\",\"4周前\":\"--4W\",\"昨天\":\"--1d\"}\n```"),
        HumanMessage(content=f"根据问题`{question}`提取时间。")
    ]

    return messages


def get_describe(question, data):
    cdata = deepcopy(data)

    unit_mapping = {
        # "pH": "(无量纲)",
        "Cond": "(us/cm)",
        "COD": "(mg/L)",
        "COD(+AgNO3)": "(mg/L)",
        "TOC": "(mg/L)",
        "TP": "(mg/L)",
        "TN": "(mg/L)",
        "氨氮": "(mg/L)",
        "硝氮": "(mg/L)",
        "TDS": "(mg/L)",
        "生化需氧量": "(mg/L)",
        "余氯": "(mg/L)",
        "粪大肠菌群": "(MPN/L)",
        "VFA": "(mEq/L)",
        "ALK": "(mEq/L)",
        "SS": "(mg/L)",
        "污泥沉降比": "(%)",
        "MLSS": "(mg/L)",
        "MLVSS": "(mg/L)",
        "色度": "(倍)",
        "氯离子": "(mg/L)",
        "碱度": "(mg/L)",
        "硬度": "(mg/L)",
        "硫酸根": "(mg/L)",
        "硫化物": "(μg/L)",
        "FLOW": "(L/s)",
        "酸碱度": "(mg/L)",
        "TSS": "(mg/L)",
        "NH3-N":"(mg/L)",
    }

    if cdata and "res_total_data" in cdata:
        res_data = cdata["res_total_data"]
        for ky, val in res_data.items():
            flag = True
            for indice, unit in unit_mapping.items():
                if indice in ky:
                    flag = False
                    val = [[timestamp2timestr(row[0] / 1000), str(row[1]) + unit] for row in val]
                    break
            if flag:
                # val = [[timestamp2timestr(row[0] / 1000), str(row[1]) + "(无量纲)"] for row in val]
                val = [[timestamp2timestr(row[0] / 1000), str(row[1]) ] for row in val]

            cdata["res_total_data"][ky] = val

    if not cdata or (
            not cdata.get("res_total_data") and not cdata.get("res_total_tip") and not cdata.get("res_total_table")):
        cdata = "没有查询到符合问题的数据"

    example = {
        "a检测值 SOP": [[1743017200000, "6.9(无量纲)"]],
        "a检测值 ZIK": [[1743017220000, "7.1(us/cm)"]],
        "b检测值 ZIK": [[1743017270000, "2.7(us/cm)"]]
    }

    messages = [
        SystemMessage(content=f"""你是一个数据总结专家，你需要对查询到的数据进行总结

1.下面是个例子
比如：结合问题【查询xxx异常数据】和符合问题的数据：\n{example}，进行一段100字话内的总结,不用markdwon格式
输出：查询到xxx异常数据：a检测值SOP异常值 6.9(无量纲)；a检测值ZIK异常值 7.1(us/cm)；b检测值ZIK异常值 2.7(us/cm)
2.如果数据为空，说明该符合该问题筛选条件的数据为空。
3.如果总结出现时间，请用口语化的说法,比如2025-10-01改为2025年10月1日，12:00改为12点
4.如果数据中有单位，总结中需要加上.
5.药剂的单位是KG
"""),
        HumanMessage(content=f"结合问题【{question}】和数据：\n{cdata}，进行一段100字话的总结,不用markdwon格式")
    ]

    return messages


def get_route_prompt(question):
    messages = [
        SystemMessage(content=f"""你是一个数据管家，如果用户问题命中了下面的数据返回"bingo", 无关返回"other"
可以查询的问题如下：
1.上游来水数据
2.下游排海数据
3.厂区在线数据
4.实验室检测数据
5.巡检运行、区域巡检、巡检打卡、行打卡、巡检异常、巡检维修、巡检中发现无需维修/异常/正在维修/维修已完成的数据
6.巡检缺卡/运行缺卡
7.用电量、用水量、用蒸汽量
8.药剂管理、药剂出库、药剂入库、药剂供应商
9.污泥外运、污泥含水量、污泥重量
10.人员考勤
11.设备清单、设备状态（运行中、维修中/故障设备、异常状态设备、停用设备）、设备详情数据
"""),
        HumanMessage(content=f"根据问题【{question}】选择返回bingo或other")
    ]

    return messages
